package com.pipi.biyesheji.service.impl;

import com.pipi.biyesheji.dao.manager.OrderManager;
import com.pipi.biyesheji.dao.model.OrderDO;
import com.pipi.biyesheji.dao.query.OrderQuery;
import com.pipi.biyesheji.dao.support.PageResult;
import com.pipi.biyesheji.enums.AllEnums;
import com.pipi.biyesheji.pojo.Customer;
import com.pipi.biyesheji.pojo.Order;
import com.pipi.biyesheji.pojo.OrderItem;
import com.pipi.biyesheji.service.CustomerService;
import com.pipi.biyesheji.service.OrderItemService;
import com.pipi.biyesheji.service.OrderService;
import com.pipi.biyesheji.util.BeanUtils;
import com.pipi.biyesheji.util.Page;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author pipi
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderManager orderManager;
    @Autowired
    CustomerService customerService;
    @Autowired
    OrderItemService orderItemService;

    @Override
    public void save(Order order) {
        OrderDO orderDO = BeanUtils.createCloneBean(order, OrderDO.class);
        orderManager.insertSelective(orderDO);
    }

    @Override
    public void del(Long id) {
        orderManager.deleteByPrimaryKey(id);
    }

    @Override
    public void update(Order order) {
        OrderDO orderDO = orderManager.selectByPrimaryKey(order.getId());
        long createTime = orderDO.getGmtCreate().getTime();
        long currentTime = System.currentTimeMillis();
        long time = 5 * 60 * 1000;
        if (Objects.equals(AllEnums.OrderStatusEnum.NO_SHIPMENT.getCode(), orderDO.getStatus())
                && currentTime - createTime > time) {
            throw new RuntimeException("下单时间超过5分钟，不可取消");
        }
        BeanUtils.copyNotNullProperties(order, orderDO);
        orderManager.updateByPrimaryKeySelective(orderDO);
    }

    @Override
    public Order get(Long id) {
        OrderDO orderDO = orderManager.selectByPrimaryKey(id);
        return buildOrder(orderDO);
    }

    @Override
    public PageResult<Order> list(Page page){
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setPageNo(page.getStart());
        orderQuery.setPageSize(page.getCount());
        orderQuery.setOrderByClause("id desc");
        PageResult<OrderDO> pageResult = orderManager.selectByQueryWithPage(orderQuery);
        if (CollectionUtils.isEmpty(pageResult.getResult()))  {
            return PageResult.createPageResult();
        }
        List<Order> orders = buildOrders(pageResult.getResult());
        setCust(orders);
        return PageResult.createPageResult(orders, pageResult.getPageInfo());
    }
    //给每个订单设置客户
    public void setCust(List<Order> os){
        for (Order o : os) {
            setCust(o);
        }
    }
    //给客户实体设置客户
    public void setCust(Order o){
        Long cstid = o.getCstid();
        Customer customer = customerService.get(cstid);
        o.setCustomer(customer);
    }

    @Transactional(propagation= Propagation.REQUIRED,rollbackForClassName="Exception")
    @Override
    public float add(Order o, List<OrderItem> ois) {
        float total = 0;
        //新增订单数据
        save(o);

        if(false) {
            //用来模拟当增加订单后出现异常，观察事务管理是否预期发生。（需要把false修改为true才能观察到）
            throw new RuntimeException();
        }

        for (OrderItem oi: ois) {
            //给订单项设置订单id 关联起来
            oi.setOid(o.getId());
            orderItemService.update(oi);
            //商品的价格+当前订单项购买数量
            total+=oi.getProduct().getPrice()*oi.getNumber();
        }
        return total;
    }

    @Override
    public List<Order> list(Long cstid) {
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setOrderByClause("id desc");
        orderQuery.createCriteria().andCstidEqualTo(cstid);
        List<OrderDO> orderDOS = orderManager.selectByQuery(orderQuery);
        return buildOrders(orderDOS);

    }

    private List<Order> buildOrders(List<OrderDO> orderDOS) {
        return orderDOS.stream().map(this::buildOrder).collect(Collectors.toList());
    }

    private Order buildOrder(OrderDO orderDO) {
        if (Objects.isNull(orderDO)) {
            return null;
        }
        return BeanUtils.createCloneBean(orderDO, Order.class);
    }

}
